package com.ruoyi.system.utils;

import com.aliyun.oss.OSS;
import com.aliyun.oss.OSSClientBuilder;
import com.ruoyi.common.core.utils.StringUtils;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.MediaType;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.commons.CommonsMultipartFile;

import java.io.*;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

public class TencentUtils {
    private static final Logger logger = LoggerFactory.getLogger(TencentUtils.class);
    private String endpoint = "http://oss-cn-guangzhou.aliyuncs.com";
    // 云账号AccessKey有所有API访问权限，建议遵循阿里云安全最佳实践，创建并使用RAM子账号进行API访问或日常运维，请登录 https://ram.console.aliyun.com 创建。
    private String accessKeyId = "LTAI5tK3Y2uKk8xQLn5vanLp";
    private String accessKeySecret = "Yl1XWYJzSR7QkXZMai1UKNibsUuSMd";
    private String bucketName = "guofangoss";

    private static TencentUtils instance;
    // 1 初始化用户身份信息(secretId, secretKey)
    OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);

    public static TencentUtils getInstance() {
        if (instance == null) {
            instance = new TencentUtils();
        }
        return instance;
    }

    /**
     * Description: 判断Cos服务文件上传时文件的contentType
     * @param filenameExtension 文件后缀
     * @return String
     */
    public static String getcontentType(String filenameExtension) {
        if (filenameExtension.equalsIgnoreCase("bmp")) {
            return "image/bmp";
        }
        if (filenameExtension.equalsIgnoreCase("gif")) {
            return "image/gif";
        }
        if (filenameExtension.equalsIgnoreCase("jpeg") || filenameExtension.equalsIgnoreCase("jpg")
                || filenameExtension.equalsIgnoreCase("png")) {
            return "image/jpeg";
        }
        if (filenameExtension.equalsIgnoreCase("html")) {
            return "text/html";
        }
        if (filenameExtension.equalsIgnoreCase("txt")) {
            return "text/plain";
        }
        if (filenameExtension.equalsIgnoreCase("vsd")) {
            return "application/vnd.visio";
        }
        if (filenameExtension.equalsIgnoreCase("pptx") || filenameExtension.equalsIgnoreCase("ppt")) {
            return "application/vnd.ms-powerpoint";
        }
        if (filenameExtension.equalsIgnoreCase("docx") || filenameExtension.equalsIgnoreCase("doc")) {
            return "application/msword";
        }
        if (filenameExtension.equalsIgnoreCase("xml")) {
            return "text/xml";
        }
        return "image/jpeg";
    }

    /**
     * 上传到COS服务器 如果同名文件会覆盖服务器上的
     * @param instream 文件流
     * @param fileName 文件名称 包括后缀名
     * @return 出错返回"" ,唯一MD5数字签名
     */
    public List<Map<String, String>> uploadFile2Cos(InputStream instream, String fileName) {
        List<Map<String, String>> fileNameList = new ArrayList<>();
        Map<String, String> map = new HashMap<>();
        ossClient.putObject(bucketName, fileName, instream);
        //关闭OSSClient。
        //ossClient.shutdown();
        map.put(bucketName, fileName);
        fileNameList.add(map);
        return fileNameList;
    }

    /**
     * Description: 上传图片到阿里云
     * @param file 文件对象
     * @return String 阿里云文件URL
     */
    public String uploadFile2Cos(MultipartFile file) throws Exception {
        String originalFilename = file.getOriginalFilename();
        String substring = "png";
        if (!"blob".equals(originalFilename)) {
            substring = originalFilename.substring(originalFilename.lastIndexOf(".")).toLowerCase();
        }
        LocalDate date = LocalDate.now();
        DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
        // 指定要上传到 COS 上的路径
        String fileName = (System.currentTimeMillis() + substring);// 保存文件的名字命名方式
        try {
            InputStream inputStream = file.getInputStream();
            fileName = "uploadsc/" + formatter.format(date) + "/" + fileName;
            uploadFile2Cos(inputStream, fileName);
            return "https://guofangoss.oss-cn-guangzhou.aliyuncs.com/" + fileName;
        } catch (Exception e) {
            throw new Exception("图片上传失败");
        }
    }

    /**
     * 简单文件上传, 最大支持 5 GB, 适用于小文件上传, 建议 20 M 以下的文件使用该接口 大文件上传请参照 API 文档高级 API 上传
     * @param localFilePath 文件路径
     * @return String 阿里云文件URL
     */
    public String uploadfile(String localFilePath) {
        File localFile = new File(localFilePath);
        String fileName = localFile.getName();
        String url = null;
        try {
            // 指定要上传到 COS 上的路径
            String suffix = this.getFileSuffixName(fileName);
            fileName = (System.currentTimeMillis() + suffix);// 保存文件的名字命名方式
            ossClient.putObject(bucketName, fileName, localFile);
            LocalDate date = LocalDate.now();
            DateTimeFormatter formatter = DateTimeFormatter.ofPattern("yyyyMMdd");
            url = "https://guofangoss.oss-cn-guangzhou.aliyuncs.com/upload/" + formatter.format(date) + "/" + fileName;
        } catch (Exception e) {
            // 打印日志中的错误信息
            logger.error(e.getMessage() + e.getStackTrace());
        } finally {
            // 关闭客户端(关闭后台线程)
            /*if(ossClient != null) {
                ossClient.shutdown();
            }*/
        }
        return url;
    }

    /**
     * 删除阿里云上文件对象
     * @param key 阿里云文件URL
     */
    public void del(String key){
        // 指定要删除的 bucket 和对象键
        ossClient.deleteObject(bucketName, key);
    }

    public static String getFileSuffixName(String fileName) {
        String suffixName = null;
        if (!StringUtils.isEmpty(fileName)) {
            suffixName = fileName.substring(fileName.lastIndexOf(".") + 1);
        }
        return suffixName;
    }

    public static MultipartFile getMultipartFile(File file) {
        FileItem item = new DiskFileItemFactory().createItem("file"
                , MediaType.MULTIPART_FORM_DATA_VALUE
                , true
                , file.getName());
        try (InputStream input = new FileInputStream(file);
             OutputStream os = item.getOutputStream()) {
            // 流转移
            IOUtils.copy(input, os);
        } catch (Exception e) {
            throw new IllegalArgumentException("Invalid file: " + e, e);
        }
        return new CommonsMultipartFile(item);
    }

    public Long getObjectSize(String key) {
        InputStream objectContent = ossClient.getObject(bucketName, key).getObjectContent();
        long size = 0;
        try {
            size = objectContent.available();
        }catch (IOException ex) {}
        return Long.valueOf(size);
    }
}
